package com.example.alspringaop.spring.framework.aop;

import com.example.alspringaop.spring.framework.aop.aspect.ALAdvice;
import com.example.alspringaop.spring.framework.aop.support.ALAdvisedSupport;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;

/**
 * Java的动态代理类
 */
public class ALJdkDynamicAopProxy implements InvocationHandler {

    private ALAdvisedSupport config;

    public ALJdkDynamicAopProxy(ALAdvisedSupport config) {
        this.config = config;
    }



    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Map<String, ALAdvice> advices = config.getAdvices(method,null);
        Object  returnValue;
        try{
            invokeAdivce(advices.get("before"));
            returnValue = method.invoke(this.config.getTarget(),args);
            invokeAdivce(advices.get("after"));
        }catch (Exception e){
            //执行异常处理的方法
            invokeAdivce(advices.get("afterThrow"));
            throw e;
        }
        return returnValue;
    }

    /**
     * 执行代理方法
     * @param advice
     */
    private void invokeAdivce(ALAdvice advice) {
        try {
            advice.getAdviceMethod().invoke(advice.getAspect());
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取代理对象
     * @return
     */
    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(), this.config.getTargetClass().getInterfaces(),this);
    }
}
